package com.wetool.jpa;

import java.util.ArrayList;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.redis.connection.SortParameters.Order;

import com.alipay.api.domain.ShopInfo;
import com.wetool.entity.Merchant;
import com.wetool.model.SearchParam;
import com.wetool.model.dto.ShopInfoDto;

/**
 * 描述：店铺自定义查询
 * 
 * @author lesim
 * @since 1.0
 */
public class ShopInfoSpec implements Specification<ShopInfoDto> {

	private final SearchParam param;

	public ShopInfoSpec(SearchParam param) {
		this.param = param;
	}
	@Autowired
	private ShopInfoDto shopInfoDto;
	@Override
	public Predicate toPredicate(Root<ShopInfoDto> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
		List<Predicate> predicates = new ArrayList<>();
		// like 关键字
		if (StringUtils.isNotBlank(param.getKey())) {
			Predicate pred = cb.or(cb.like(cb.lower(root.get("name")), "%" + param.getKey().toLowerCase() + "%"));
			pred = cb.or(pred, cb.like(cb.lower(root.get("mobile")), "%" + param.getKey().toLowerCase() + "%"));
			predicates.add(pred);
		}
		// 子表查询 地区编号
		if (StringUtils.isNotEmpty(param.getAreaId())) {
			predicates.add(cb.like(root.get("area").get("areaIds"), "%" + param.getAreaId().toLowerCase() + "%"));
		}
		// 子表查询 商家id
		if (param.getMerchantId() != null) {
			predicates.add(cb.equal(root.get("merchant").get("id"), param.getMerchantId()));
		}

		/* 服务商id 查询所属店铺id */
		if (param.getSpId() != null) {
			Join<Merchant, ShopInfoDto> join = root.join("merchant", JoinType.INNER);
			predicates.add(cb.equal(join.get("spId"), param.getSpId()));
		}
		// 日期格式大于
		if (param.getFrom() != null) {
			predicates.add(cb.greaterThan(root.get("createDate"), param.getFrom()));
		}
		if (param.getTo() != null) {
			predicates.add(cb.lessThan(root.get("createDate"), param.getTo()));
		}

//		if (param.getLongitude() != null && param.getLatitude() != null) {
//			// 查询距离在111km以内
//			predicates.add(
//					cb.greaterThan(cb.toDouble(root.get("longitude")), param.getGelongitude()));
//			predicates
//					.add(cb.lessThan(cb.toDouble(root.get("longitude")), param.getLelongitude()));
//			predicates.add(
//					cb.greaterThan(cb.toDouble(root.get("latitude")), param.getGelatitude()));
//			predicates
//					.add(cb.lessThan(cb.toDouble(root.get("latitude")), param.getLelatitude()));
//		}
		predicates.add(cb.isNotNull(root.get("longitude")));
		predicates.add(cb.isNotNull(root.get("latitude")));
		predicates.add(cb.notEqual(root.get("isDeleted"), 1));
		return andTogether(predicates, cb);
	}
	private static Double rad(Double d) {
		return d * Math.PI / 180D ;
	}
	public static Double setDistance( Double longitude, Double latitude, SearchParam param ) {
		Double EARTH_RADIUS = 6378137D;//地球半径
		Double distance = 0D;
		if (longitude == null || latitude == null) {
			return distance;
		}
	    Double radLat1 = rad(latitude);  
        Double radLat2 = rad(param.getLatitude());  
        Double a = radLat1 - radLat2;  
        Double b = rad(longitude) - rad(param.getLongitude());  
        distance = 2 * Math.asin(  
             Math.sqrt(  
                 Math.pow(Math.sin(a/2),2)   
                 + Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(b/2),2)  
            )  
         );  
        distance = distance * EARTH_RADIUS;  
        distance = (double) (Math.round(distance * 10000) / 10000);  
		return distance;
	}

	private Predicate andTogether(List<Predicate> predicates, CriteriaBuilder cb) {
		return cb.and(predicates.toArray(new Predicate[0]));
	}
}